/**
 * pinia-plugin.js
 * liruilin
 * 2025-2-28
 * @param {object} globalOptions 
 * @returns 
 */
export default function piniaPlugin(globalOptions = {}) {
    let globalState = {}
    const pathCache = new Map()

    // 路径解析器（带缓存）
    const parsePath = (path) => {
        if (pathCache.has(path)) return pathCache.get(path)
        const keys = String(path)
            .replace(/$$(\d+)$$/g, '.$1') // 转换数组索引
            .split('.')
            .filter(k => k !== '')
        pathCache.set(path, keys)
        return keys
    }

    // 状态操作工具
    const stateTools = {
        // 安全获取嵌套属性
        get(state, path) {
            return parsePath(path).reduce((obj, key) => obj?.[key], state)
        },

        // 精准设置属性（自动创建路径）
        set(state, path, value) {
            const keys = parsePath(path)
            let current = state
            for (let i = 0; i < keys.length - 1; i++) {
                const key = keys[i]
                if (!current[key] || typeof current[key] !== 'object') {
                    current[key] = typeof keys[i + 1] === 'number' ? [] : {}
                }
                current = current[key]
            }
            current[keys[keys.length - 1]] = value
            return state
        }
    }

    // 严格过滤配置路径
    const filterState = (source, paths) => {
        if (!paths?.length) return undefined // 无配置路径时返回undefined

        return paths.reduce((acc, path) => {
            const keys = parsePath(path)
            let src = source
            let dest = acc

            keys.forEach((key, index) => {
                if (src?.[key] === undefined) return

                if (index === keys.length - 1) {
                    dest[key] = src[key]
                } else {
                    dest[key] = dest[key] || (typeof keys[index + 1] === 'number' ? [] : {})
                    dest = dest[key]
                    src = src[key]
                }
            })

            return acc
        }, Array.isArray(source) ? [] : {})
    }

    return (context) => {
        const {
            store
        } = context
        const mergedOptions = {
            globalKey: 'pinia-global-state',
            storage: 'local',
            ...globalOptions,
            ...(context?.options?.persistedstate || {})
        }

        // 添加实例方法
        store.getState = (path) =>
            path ? stateTools.get(store.$state, path) : JSON.parse(JSON.stringify(store.$state))

        store.setState = (path, value) => {
            const updates = typeof path === 'object' ? path : {
                [path]: value
            }
            store.$patch(state => {
                Object.entries(updates).forEach(([p, v]) => {
                    stateTools.set(state, p, v)
                })
            })
        }

        // 初始化加载（严格模式）
        const loadPersistedState = () => {
            try {
                const storage = mergedOptions.storage === 'session' ?
                    uni.getStorageSync :
                    uni.getStorageSync
                const saved = storage(mergedOptions.globalKey)
                if (!saved) return

                const parsed = JSON.parse(saved)[store.$id]
                if (!parsed || !mergedOptions.paths?.length) return

                // 只注入配置路径的数据
                const filtered = filterState(parsed, mergedOptions.paths)
                filtered && store.$patch(filtered)
            } catch (e) {
                console.error('Persist load error:', e)
            }
        }

        // 持久化方法（绝对隔离）
        const savePersistedState = () => {

            try {
                // 严格过滤出配置路径
                const stateToSave = filterState(store.$state, mergedOptions.paths)
                if (stateToSave === undefined) return // 无配置路径时不保存

                // 更新全局状态
                globalState = {
                    ...globalState,
                    [store.$id]: stateToSave
                }
                // 写入存储
                const storage = mergedOptions.storage === 'session' ?
                    uni.setStorageSync :
                    uni.setStorageSync
                storage(mergedOptions.globalKey, JSON.stringify(globalState))
            } catch (e) {
                console.error('Persist save error:', e)
            }
        }

        // 首次加载
        loadPersistedState()

        // 自动保存（带防抖）
        let saveTimer
        store.$subscribe(() => {

            clearTimeout(saveTimer)
            saveTimer = setTimeout(savePersistedState, 300)
        })
    }
}